package com.learn.service.impl;

import com.learn.apis.AccountFeignApi;
import com.learn.apis.StorageFeignApi;
import com.learn.entities.Order;
import com.learn.mapper.OrderMapper;
import com.learn.service.OrderService;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

/**
 * @author DJJ_F
 * @version 1.0
 * @date 2025/08/09
 * @description ch13 seata
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private StorageFeignApi storageFeignApi;
    @Resource
    private AccountFeignApi accountFeignApi;

    /**
     * TC可以说就是seata自己
     * 此时OrderService即是TM也是RM
     * @param order
     */
    @Override
    @GlobalTransactional(name = "order-service", rollbackFor = Exception.class)
    public void create(Order order) {
        String xid = RootContext.getXID();
        log.info("--------start transaction, xid: " + xid);

        order.setStatus(0);
        int result = orderMapper.insertSelective(order);

        if (result > 0) {
            Order orderDB = orderMapper.selectOne(order);
            log.info("--------change storage");
            storageFeignApi.decrease(orderDB.getProductId(), orderDB.getCount());

            log.info("--------change account");
            accountFeignApi.decrease(orderDB.getUserId(), orderDB.getMoney());

            log.info("--------change order");
            orderDB.setStatus(1);

            // 1. 创建Example对象
            Example example = new Example(Order.class);
            // 2. 获取Criteria并设置条件
            Example.Criteria criteria = example.createCriteria()
                    .andEqualTo("userId", orderDB.getUserId())
                    .andEqualTo("status", 0);
            // 3. 将Example对象传入update方法，注意这里传的是example而非criteria
            int i = orderMapper.updateByExampleSelective(orderDB, example);

            log.info("--------finish order, result: " + i);
            log.info("--------orderFromDB info: " + orderDB);
        }

        log.info("--------end transaction, xid: " + xid);
        System.out.println();
    }
}
